package com.servlet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONException;
import org.json.JSONObject;

import test.demo.Record;
import test.demo.Staff;
import test.demo.db.RecordOperation;
import test.demo.db.StaffOperation;

public class PunchCardServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		try {
			String name = (String) req.getSession()
					.getAttribute("session_name");
			StaffOperation staffOperation = StaffOperation.getInstance();
			RecordOperation recordOperation = RecordOperation.getInstance();
			Staff staff = staffOperation.queryFromName(name).get(0);

			String date = new SimpleDateFormat("yyyy-MM-dd").format(Calendar
					.getInstance().getTime());
			int staffId = staff.getId();
			Record record = recordOperation.queryRecord(staffId, date);
			String currentTime = new SimpleDateFormat("HH:mm").format(Calendar
					.getInstance().getTime());
			if (record != null) {
				record.setEndTime(currentTime);
				record.setIp(getLocate(getIpAddr(req)));
				recordOperation.updateRecordEndTime(record);
			} else {
				record = new Record();
				record.setStaffId(staffId);
				record.setStartTime(currentTime);
				record.setEndTime(currentTime);
				record.setDate(date);
				record.setIp(getLocate(getIpAddr(req)));
				recordOperation.insertRecord(record);
			}

			String dateWithMonth = new SimpleDateFormat("yyyy-MM")
					.format(Calendar.getInstance().getTime());
			List<Record> records = recordOperation.queryFromStaffId(staffId,
					dateWithMonth);
			req.setAttribute("queried_list", records);
			req.getRequestDispatcher("punchCard.jsp").forward(req, resp);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IndexOutOfBoundsException e) {
			PrintWriter out = resp.getWriter();
			out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN \">\n"
					+ "<HTML>\n"
					+ "<HEAD><TITLE>Hello WWW</TITLE></HEAD>\n"
					+ "<BODY>\n"
					+ "<H1>Error!!! login in first!!!</H1>\n"
					+ "</BODY></HTML>");
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * get the ip address from request.
	 * @param request
	 * @return
	 */
	private String getIpAddr(HttpServletRequest request) {
		String ipAddress = null;
		// ipAddress = request.getRemoteAddr();
		ipAddress = request.getHeader("x-forwarded-for");
		if (ipAddress == null || ipAddress.length() == 0
				|| "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.length() == 0
				|| "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.length() == 0
				|| "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getRemoteAddr();
			if (ipAddress.equals("127.0.0.1")) {
				InetAddress inet = null;
				try {
					inet = InetAddress.getLocalHost();
				} catch (UnknownHostException e) {
					e.printStackTrace();
				}
				ipAddress = inet.getHostAddress();
			}
		}
		if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
			if (ipAddress.indexOf(",") > 0) {
				ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
			}
		}
		return ipAddress;
	}

	private String readAll(Reader rd) throws IOException {
		StringBuilder sb = new StringBuilder();
		int cp;
		while ((cp = rd.read()) != -1) {
			sb.append((char) cp);
		}
		return sb.toString();
	}

	/**
	 * get JSONObject
	 * @param url
	 * @return
	 * @throws IOException
	 * @throws JSONException
	 */
	private JSONObject readJsonFromUrl(String url) throws IOException,
			JSONException {
		InputStream is = new URL(url).openStream();
		try {
			BufferedReader rd = new BufferedReader(new InputStreamReader(is,
					Charset.forName("UTF-8")));
			String jsonText = readAll(rd);
			JSONObject json = new JSONObject(jsonText);
			return json;
		} finally {
			is.close();
		}
	}

	/**
	 * Get locate string
	 * @param ip
	 * @return
	 * @throws IOException
	 * @throws JSONException
	 */
	private String getLocate(String ip) throws IOException, JSONException {
		JSONObject json = readJsonFromUrl("http://api.map.baidu.com/location/ip?ak=9be82d59a89318923b75ac0544de30af&ip="+ip);
		JSONObject location = ((JSONObject)((JSONObject) json.get("content"))
				.get("point"));
		return location.get("x") + "," + location.get("y");
	}

}
